// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using Microsoft.Sbom.Common.Config;
using Microsoft.Sbom.Common.Extensions;
using Microsoft.Sbom.Common.Utils;
using Microsoft.Sbom.Contracts;
using Microsoft.Sbom.Extensions;
using Microsoft.Sbom.Extensions.Entities;

namespace Microsoft.Sbom.Api.Metadata;

/// <summary>
/// Provides metadata provided by the user from the SBOM Api.
/// </summary>
public class SbomApiMetadataProvider : IMetadataProvider
{
    private readonly SbomMetadata metadata;
    private readonly IConfiguration configuration;

    public SbomApiMetadataProvider(SbomMetadata metadata, IConfiguration configuration)
    {
        this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
        this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
        PopulateMetadata();
    }

    /// <summary>
    /// Gets or sets stores the metadata that is generated by this metadata provider.
    /// </summary>
    public IDictionary<MetadataKey, object> MetadataDictionary { get; set; } = new Dictionary<MetadataKey, object>();

    public string BuildEnvironmentName
    {
        get
        {
            if (MetadataDictionary.TryGetValue(MetadataKey.BuildEnvironmentName, out var name))
            {
                return name as string;
            }

            return null;
        }
    }

    public string GetDocumentNamespaceUri()
    {
        var nsUniquePart = Uri.EscapeDataString(configuration.NamespaceUriUniquePart?.Value ?? IdentifierUtils.GetShortGuid(Guid.NewGuid()));
        var packageName = Uri.EscapeDataString(MetadataDictionary[MetadataKey.PackageName] as string);
        var packageVersion = Uri.EscapeDataString(MetadataDictionary[MetadataKey.PackageVersion] as string);

        return string.Join("/", configuration.NamespaceUriBase.Value, packageName, packageVersion, nsUniquePart);
    }

    private void PopulateMetadata()
    {
        MetadataDictionary.AddIfKeyNotPresentAndValueNotNull(MetadataKey.Build_BuildId, metadata.BuildId);
        MetadataDictionary.AddIfKeyNotPresentAndValueNotNull(MetadataKey.PackageName, metadata.PackageName);
        MetadataDictionary.AddIfKeyNotPresentAndValueNotNull(MetadataKey.PackageVersion, metadata.PackageVersion);
        MetadataDictionary.AddIfKeyNotPresentAndValueNotNull(MetadataKey.Build_DefinitionName, metadata.BuildName);
        MetadataDictionary.AddIfKeyNotPresentAndValueNotNull(MetadataKey.Build_Repository_Uri, metadata.RepositoryUri);
        MetadataDictionary.AddIfKeyNotPresentAndValueNotNull(MetadataKey.Build_SourceBranchName, metadata.Branch);
        MetadataDictionary.AddIfKeyNotPresentAndValueNotNull(MetadataKey.Build_SourceVersion, metadata.CommitId);
        MetadataDictionary.AddIfKeyNotPresentAndValueNotNull(MetadataKey.BuildEnvironmentName, metadata.BuildEnvironmentName);
    }
}
